using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Mvc;
using FwkLight.CodeExtensions;

namespace FwkLight.Web.UserSession
{
  public interface IBaseUserSession
  {
    void PushMessage ( MessageType messageType, string message );
    IList<FlashMessage> PopErrorMessages ( );
    IList<FlashMessage> PopSuccessMessages ( );
    bool IsAuthenticated { get; }
    TempDataDictionary TempData { set; }
    string UserName { get; }
  }
  
  public class BaseUserSession : IBaseUserSession
  {
    private TempDataDictionary _tempData;

    public void PushMessage ( MessageType messageType, string message )
    {
      getMessagesStack().Push(new FlashMessage(messageType, message));
    }

    public IList<FlashMessage> PopErrorMessages ( )
    {
      return PopMessagesByType(MessageType.Error);
    }

    public IList<FlashMessage> PopSuccessMessages ( )
    {
      return PopMessagesByType(MessageType.Success);
    }

    public bool IsAuthenticated
    {
      get { return HttpContext.Current.User.Identity.IsAuthenticated; }
    }

    private IList<FlashMessage> PopMessagesByType ( MessageType msgType )
    {
      Stack<FlashMessage> tempMessages = getMessagesStack();

      IList<FlashMessage> flashMessages = new List<FlashMessage>();
      if (tempMessages.Count == 0)
        return flashMessages;

      IList<FlashMessage> messagesToPushBack = new List<FlashMessage>();

      while (tempMessages.Count > 0)
      {
        FlashMessage message = tempMessages.Pop();
        if (message.Type != msgType)
          messagesToPushBack.Add(message);
        else
          flashMessages.Add(message);
      }

      Stack<FlashMessage> messagesStack = getMessagesStack();
      messagesToPushBack.ForEach(x => messagesStack.Push(x));

      return flashMessages;
    }
    public TempDataDictionary TempData
    {
      set { _tempData = value; }
    }

    public string UserName
    {
      get { return HttpContext.Current.User.Identity.Name; }
    }

    private Stack<FlashMessage> getMessagesStack ( )
    {
      ensureFlashMessageCollectionInit();
      return _tempData["flashMessages"] as Stack<FlashMessage>;
    }

    private void ensureFlashMessageCollectionInit ( )
    {
      if ((_tempData["flashMessages"] as Stack<FlashMessage>) == null || (_tempData["flashMessages"] as Stack<FlashMessage>).Count == 0)
        _tempData["flashMessages"] = new Stack<FlashMessage>();
    }
  }
}